<?php
/**
 * 支持两种方式的interceptor切入
 * 第一种
 * 	class DemoController implements Pfinal_Controller_Interceptable{
 * 		
 * 		public function getInterceptors(){};
 * 	}
 * 第二种 支持注解的方式
 * 	class DemoController {
 * 		/**
 * 		 **@method(PermisionInterceptor.class)
 * 		/
 * 		public function demoAction(){}
 * 	}
 * @author yusaint
 * @since 2014-2-25
 * @package Pfinal
 */
class Pfinal_Interceptor_Builder {
	
	protected $instance;
	
	protected $controller;
	
	protected $action;
	
	public function __construct($object,$method){
		$this->controller = $object;
		$this->action = $method;
		$this->instance = new ReflectionClass($object);
	}
	
	/**
	 * 
	 */
	public function getInterceptors(PfinalConfig $kernelConfig){
		$interceptorMode = $kernelConfig->getConstant()->getInterceptorMode();
		if ($interceptorMode === Pfinal_Config_Constant::MODE_INTERFACE){
			if ($this->controller instanceof Pfinal_Controller_Interceptable){
				$interceptorConfig = new Pfinal_Config_Interceptor();
				$this->controller->addInterceptor($interceptorConfig);
				return $interceptorConfig->getInterceptors();
			}
		}elseif ($interceptorMode === Pfinal_Config_Constant::MODE_INNOTATION){
			$methodInstance = new ReflectionMethod($this->controller, $this->action);
			$doc = $methodInstance->getDocComment();
			if (!empty($doc)||$doc!==false){
				return $this->parseInterceptorsFromDoc($doc);
			}
		}
		return array();
	}
	
	/**
	 * 正则匹配解析出
	 * @interceptor(class.method)这种结构
	 * @param unknown_type $doc
	 */
	private function parseInterceptorsFromDoc($doc){
		$interceptors = array();
		$pattern = '/\@interceptor\((?P<classname>\w*)\.(?P<method>\w*)\)/i';
		preg_match_all($pattern, $doc, $matches);
		if (!empty($matches)){
			if (isset($matches['classname'])&&isset($matches['method'])){
				if (count($matches['classname'])!==count($matches['method'])){
					throw new Pfinal_Exception_Runtime("unmatched interceptor innovation in ".$this->action);
				}
				foreach ($matches['classname'] as $k=>$classname){
					$class = new $classname;
					array_push($interceptors,$class);
				}
			}
		}
		return $interceptors;
	}
}

?>